
#include <iostream>
#include <string>
#include <memory>

//抽象电脑类
class Computer
{
public:
    using ptr = std::shared_ptr<Computer>;
    Computer()
    {}

    void SetBoard(const std::string& board)
    {
        _board = board;
    }

    void SetDisplay(const std::string& display)
    {
        _display = display;
    }

    virtual void SetOs() = 0;

    void showParamaters()
    {
        std::string parm = "computer Paramaters:\n";
        parm += "\tBoard" + _board +"\n";
        parm += "\tDisplay" + _display + "\n";
        parm += "\tOs" + _os +"\n";
        std::cout << parm << std::endl;
    }
protected:
    std::string _board;
    std::string _display;
    std::string _os;
};

//具体产品类
class MacBook : public Computer
{
public:
    MacBook()
    {}

    void SetOs() override 
    {
        _os = "Mac Book X12";
    }
};

//抽象建造者类：包含创建一个产品对象的各个部件的抽象接口
class Builder
{
public:
    using ptr = std::shared_ptr<Builder>;

    virtual void buildBoard(const std::string& board) = 0;
    virtual void buildDisplay(const std::string& display) = 0;
    virtual void buildOs() = 0;
    virtual Computer::ptr build() = 0;

private:
};

//具体产品的具体建造者类：实现抽象接口，构建和组装各个部件
class MacBookBuilder : public Builder
{
public:
    MacBookBuilder()
        :_computer(new MacBook())//初始化_computer
    {}

    using ptr = std::shared_ptr<MacBookBuilder>;
    void buildBoard(const std::string& board) override
    {
        _computer->SetBoard(board);
    }
    virtual void buildDisplay(const std::string& display) override
    {
        _computer->SetDisplay(display);
    }
    virtual void buildOs() override
    {
        _computer->SetOs();
    }
    virtual Computer::ptr build() override
    {
        return _computer;
    }

private:
    Computer::ptr _computer;
};

//指挥者类，提供给调用者使用，通过指挥者构造复杂产品
class Director
{
public:
    Director(Builder* builder)
        :_builder(builder)
    {}

    void Construct(const std::string& board,const std::string& display)
    {
        _builder->buildBoard(board);
        _builder->buildDisplay(display);
        _builder->buildOs();       
    }   
private:
    Builder::ptr _builder;
};
int main()
{
    Builder* builder = new MacBookBuilder();
    std::unique_ptr<Director>dir(new Director(builder));
    dir->Construct("三星主板","联想显示器");
    Computer::ptr computer =  builder->build();
    computer->showParamaters();
    return 0;
}